/*******************************************************}
{                                                       }
{       Yet Another YAML Reader & Writer                }
{       for several languages                           }
{                                                       }
{       2004..2005, 2008 YT                             }
{                                                       }
{*******************************************************/

#ifndef __DYAYAML__
#define __DYAYAML__

#include "dyazdef.h"

#ifdef __cplusplus
namespace dyayaml {
extern "C" {
#endif

typedef enum {
	ytk_error,
	ytk_end,
	ytk_enter_mapping,
	ytk_enter_sequence,
	ytk_leave,
	ytk_value,
} token_kind;

typedef struct {
	token_kind kind;
	unsigned name_dummy;
	unsigned name_length;
	unsigned char const *name;
	unsigned value_dummy;
	unsigned value_length;
	unsigned char const *value;
	unsigned comment_dummy;
	unsigned comment_length;
	unsigned char const *comment;
} token_struct;

#ifdef __DYAYAML__IMPLEMENTATION__
typedef enum reader_state {
	rs_error,
	rs_end,
	rs_start,
	rs_leave_0,
	rs_leave_100 = rs_leave_0 + 100,
} reader_state;
#else
	typedef unsigned char reader_state; /* expect alignment */
#endif

typedef struct {
	token_struct next;
	int line;
	unsigned indents_capacity;
	unsigned indents_length;
	int *indents;
	unsigned source_length;
	unsigned char const *source;
	reader_state state;
	void *heap;
} reader_struct;

bool INTERFACE yaml_reader_initialize(reader_struct *s, 
	unsigned source_length, unsigned char const *source,
	unsigned *type_length, unsigned char const **type);
void INTERFACE yaml_reader_finalize(reader_struct *s);
bool INTERFACE yaml_reader_advance(reader_struct *s);
bool INTERFACE yaml_reader_advance_structure(reader_struct *s);

#ifdef __DYAYAML__IMPLEMENTATION__
typedef enum {
	ws_error,
	ws_end,
	ws_start,
} writer_state;
#else
	typedef unsigned char writer_state; /* expect alignment */
#endif

typedef struct {
	unsigned output_capacity;
	unsigned output_dummy;
	unsigned output_length;
	unsigned char *output;
	int line;
	int indents_capacity;
	int indents_length;
	token_kind *indents;
	unsigned indent_string_length;
	unsigned char const *indent_string;
	unsigned line_string_length;
	unsigned char const *line_string;
	writer_state state;
	void *heap;
} writer_struct;

bool INTERFACE yaml_writer_initialize(
	writer_struct *s, 
	unsigned indent_string_length, unsigned char const *indent_string,
	unsigned line_string_length, unsigned char const *line_string,
	unsigned type_length, unsigned char const *type);
void INTERFACE yaml_writer_finalize(writer_struct *s);
bool INTERFACE yaml_writer_append(writer_struct *s, token_struct *token);

typedef void (INTERFACE *putc_t)(unsigned char c, void *context);
void INTERFACE yaml_string_escape(unsigned char const *s, int length, putc_t putc, void *context);
void INTERFACE yaml_string_extract_escape(unsigned char const *s, int length, putc_t putc, void *context);

#ifdef __HSFFI_H__
#ifndef HASKELL
#define HASKELL
#endif
#endif

#ifdef HASKELL
void * INTERFACE yaml_reader_allocate();
void INTERFACE yaml_reader_free(void *s);
token_struct * INTERFACE yaml_reader_next(reader_struct *s);
unsigned INTERFACE yaml_writer_output_length(writer_struct *s);
unsigned char *yaml_writer_output(writer_struct *s);
void * INTERFACE yaml_writer_allocate();
void INTERFACE yaml_writer_free(void *s);
token_struct * INTERFACE yaml_token_allocate(token_kind kind, 
	unsigned name_length, unsigned char const *name,
	unsigned value_length, unsigned char const *value,
	unsigned comment_length, unsigned char const *comment);
void INTERFACE yaml_token_free(token_struct *t);
token_kind INTERFACE yaml_token_kind(token_struct *t);
unsigned INTERFACE yaml_token_name_length(token_struct *t);
unsigned char *yaml_token_name(token_struct *t);
unsigned INTERFACE yaml_token_value_length(token_struct *t);
unsigned char *yaml_token_value(token_struct *t);
unsigned INTERFACE yaml_token_comment_length(token_struct *t);
unsigned char *yaml_token_comment(token_struct *t);
#endif

#ifdef __cplusplus
}
}
#endif

#endif
